package com.astoolkit.workflow
{
	import mx.rpc.Fault;

	internal class WorkflowDelegate implements IWorkflowDelegate
	{
		private var _workflow : Workflow;
		private var _context : IWorkflowContext;
		
		public function WorkflowDelegate( inWorkflow : Workflow ) 
		{
			_workflow = inWorkflow;
		}
		
		public function get context() : IWorkflowContext
		{
			return _context;
		}
		
		public function set context( inContext : IWorkflowContext ) : void
		{
			_context = inContext;
		}
		
		public function onPrepare( inTask : IWorkflowTask ) : void
		{
			dispatchTaskEvent( WorkflowEvent.PREPARE, inTask );
		}
		
		public function onComplete( inTask : IWorkflowTask ) : void
		{
			dispatchTaskEvent( WorkflowEvent.COMPLETED, inTask );
			if( inTask != _workflow )
				_workflow.WORKFLOW_PRIVATE::onSubtaskCompleted( inTask );
		}
		
		public function onBegin( inTask : IWorkflowTask ) : void
		{
			dispatchTaskEvent( WorkflowEvent.STARTED, inTask );
			if( inTask != _workflow )
				_workflow.WORKFLOW_PRIVATE::onSubtaskBegin( inTask );
		}
		
		public function onProgress( inTask : IWorkflowTask ) : void
		{
			if( inTask.status == TaskStatus.SUSPENDED )
				return;
			dispatchTaskEvent( WorkflowEvent.PROGRESS, inTask );
			if( inTask != _workflow )
				_workflow.WORKFLOW_PRIVATE::onSubtaskProgress( inTask );
		}
		
		public function onFault( inTask : IWorkflowTask, inMessage : String, inFault : Fault = null) : void
		{
			
			dispatchTaskEvent( WorkflowEvent.FAULT, inTask, inMessage, inFault );
			if( inTask != _workflow )
				_workflow.WORKFLOW_PRIVATE::onSubtaskFault( inTask, inMessage, inFault);
		}
		
		public function onWarning( inTask : IWorkflowTask, inMessage : String, inFault : Fault = null  ) : void
		{
			dispatchTaskEvent( WorkflowEvent.WARNING, inTask, inMessage, inFault );
		}
		
		public function onSuspend( inTask : IWorkflowTask ) : void
		{
			if( inTask != _workflow )
				_workflow.WORKFLOW_PRIVATE::onSubtaskSuspended( inTask );
			if( _context.status != TaskStatus.SUSPENDED )
			{
				_context.status = TaskStatus.SUSPENDED;
				_context.dispatchEvent( new WorkflowEvent( WorkflowEvent.SUSPENDED ) );
			}
			dispatchTaskEvent( WorkflowEvent.SUSPENDED, inTask );
		}
		
		public function onResume( inTask : IWorkflowTask ) : void
		{
			if( inTask != _workflow )
				_workflow.WORKFLOW_PRIVATE::onSubtaskResumed( inTask );
			if( _context.status == TaskStatus.SUSPENDED )
			{
				_context.status = TaskStatus.RUNNING;
				_context.dispatchEvent( new WorkflowEvent( WorkflowEvent.RESUMED ) );
			}
			dispatchTaskEvent( WorkflowEvent.RESUMED, inTask );
		}
		
		public function onAbort( inTask : IWorkflowTask, inMessage : String, inFault : Fault = null) : void
		{
			dispatchTaskEvent( WorkflowEvent.ABORT, inTask, inMessage, inFault );
			if( inTask != _workflow )
				_workflow.WORKFLOW_PRIVATE::onSubtaskAbort( inTask, inMessage, inFault);
		}
		
		
		private function dispatchTaskEvent( 
			inEventType : String, 
			inTask : IWorkflowTask, 
			inMessage : String = null, 
			inFault : Fault = null ) : void
		{
			var workflow : IWorkflow = _workflow;
			while( workflow )
			{
				if( workflow.hasEventListener( inEventType ) )
					workflow.dispatchEvent( new WorkflowEvent( inEventType, inTask, inMessage, inFault ) );
				workflow = workflow.parent;
			}
		}
		
		
	}
}